from PIL import Image
import random
import numpy


# 图像工厂
class ImgFactory:

    def __init__(self, img_from, img_type='jpg'):
        self.img_from = img_from
        self.image = Image.open(self.img_from + '.' + img_type)
        self.width, self.height = self.image.size
        self.mission = 6
        self.temp = []

    # 打印进度
    def print_progress(self, row):
        print('%.2f' % (row * 100 / self.height), end='%\n')

    # 备用件-temp 用于记录图像结果
    def new_temp(self, loop=1):
        for i in range(loop):
            self.temp.append([[255] * self.width for x in range(self.height)])

    def clear_temp(self):
        self.temp = []

    def save_temp(self, lis=None, n=0):
        for i in self.temp:
            j = n % self.mission
            k = int(n / self.mission)
            image = Image.fromarray(numpy.uint8(i))
            if lis is None:
                image.save(self.img_from + '_' + str(k) + '_' + str(n + 1) + '.jpg')
            else:
                image.save(self.img_from + '_' + str(j) + '_' + str(n + 1) + '_' + str(lis[k][j]) + '.jpg')
            n += 1

    ########################################################
    block_status = [(-1, -1), (0, -1), (1, -1),
                    (-1, 0), (0, 0), (1, 0),
                    (-1, 1), (0, 1), (1, 1)]

    # 分拣
    def sorting_img(self, lis):

        image = self.image.convert('L')
        im = numpy.asarray(image)
        self.clear_temp()
        self.new_temp(self.mission * len(lis))

        for i in range(1, self.height-1):
            self.print_progress(i)
            for j in range(1, self.width-1):
                block = []
                for k in self.block_status:
                    block.append(im[i + k[0]][j + k[1]])

                x = JugMethod(block)
                for n in range(len(lis)):
                    if x.way_1(lis[n][0]):
                        self.temp[0 + n * self.mission][i][j] = 0
                    if x.way_2(lis[n][1]):
                        self.temp[1 + n * self.mission][i][j] = 0
                    if x.way_3(lis[n][2]):
                        self.temp[2 + n * self.mission][i][j] = 0
                    if x.way_4(lis[n][3]):
                        self.temp[3 + n * self.mission][i][j] = 0
                    if x.way_5(800):
                        self.temp[4 + n * self.mission][i][j] = 0
                del x, block

        self.save_temp(lis)

    # 根据不同方向的扫描进行分解
    def test_sorting(self, num):
        image = self.image.convert('L')
        im = numpy.asarray(image)
        self.clear_temp()
        self.new_temp(6)

        for i in range(1, self.height - 1):
            self.print_progress(i)
            for j in range(1, self.width - 1):
                block = []
                for k in self.block_status:
                    block.append(im[i + k[0]][j + k[1]])

                x = JugMethod(block)
                for n in range(6):
                    if x.way_5_1(num):
                        self.temp[0][i][j] = 0
                    if x.way_5_2(num):
                        self.temp[1][i][j] = 0
                    if x.way_5_3(num):
                        self.temp[2][i][j] = 0
                    if x.way_5_4(num):
                        self.temp[3][i][j] = 0
                    if x.way_5_and(num):
                        self.temp[4][i][j] = 0
                    if x.way_5_or(num):
                        self.temp[5][i][j] = 0
                del x, block

        self.save_temp()
    ####################################

    # 灰域
    def gray_area(self, x):
        if x > 240:
            return 255
        elif x <= 240 and x > 180:
            return 200
        elif x <= 180 and x > 100:
            return 150
        elif x <= 100 and x > 60:
            return 90
        else:
            return 0


    # 渲染图像 底图_纹路图
    def fit_gray(self, base, render):

        image = Image.open(base)
        img = image.convert('L')
        im1 = numpy.asarray(img)

        image = Image.open(render)
        img = image.convert('L')
        im2 = numpy.asarray(img)

        self.clear_temp()
        self.new_temp()

        for i in range(self.height):
            self.print_progress(i)
            for j in range(self.width):

                if im1[i][j] < 60:
                    self.temp[0][i][j] = (im2[i * random.randint(0,2)][j] + im1[i][j])/2
                    self.temp[0][i][j] = self.gray_area(self.temp[0][i][j])

        self.save_temp()

    # 对于彩色图像进行叠图操作
    def fit_color(self, base, render, n):
        image = Image.open(base)
        img = image.convert('L')
        im1 = numpy.asarray(img)

        image = Image.open(render)
        img = image.convert('RGB')
        im2 = numpy.asarray(img)

        self.new_temp()

        for i in range(self.height):
            self.print_progress(i)
            for j in range(self.width):

                if im1[i][j] < 60:
                    random_point = random.randint(900, 1000)/1000
                    self.temp[0+n][i][j] = im2[int(i * random_point)][int(j * random_point)]
                else:
                    self.temp[0+n][i][j] = [255,255,255]


    ###############################

    # 叠图
    def overlay(self, im1, im2, n):
        image = Image.open(im1)
        im1 = numpy.asarray(image)

        image = Image.open(im2)
        im2 = numpy.asarray(image)

        self.new_temp()
        for i in range(self.height):
            self.print_progress(i)
            for j in range(self.width):
                if (im2[i][j][0]+im2[i][j][1]+im2[i][j][2])/3 < 60:
                    self.temp[n][i][j] = im2[i][j]
                else:
                    self.temp[n][i][j] = im1[i][j]

# 判断方式
class JugMethod:

    def __init__(self, block):
        self.n = block[4]
        self.other = block[:4]+block[5:]
        self.block = block
        self.allin = sum(block)

    # 玄学判断法，x稳定于40000左右，提取线稿
    def way_1(self, x=40000):
        n1 = int((self.block[0] + self.block[1] + self.block[3]) / 3)
        n2 = int((self.block[0] + self.block[8]) / 2)
        n3 = int((self.block[0] + self.block[3] + self.block[5] + self.block[6]) / 4)
        n4 = int((self.block[1] + self.block[4]) / 2)
        if abs(n1 - self.n) ** 2 > x or abs(n2 - self.n) ** 2 > x or abs(n3 - self.n) ** 2 > x or abs(
                n4 - self.n) ** 2 > x:
            return True
        return False

    # 硬性判断，灰度像素分布于0[黑]-255[白]，可以保留暗部
    def way_2(self, x=64):
        if self.n < x:
            return True
        return False

    # 对于所有分散在周围的像素取色，生成噪点
    def way_3(self, x=0):
        num = self.allin - self.n
        num = int(num / 8)
        if self.n + x < num:
            return True
        return False

    # 玄学检测
    def way_4(self, x=255):
        n1 = random.choice(self.other)
        n2 = sum(self.other) % x
        if n1 > n2:
            return True
        return False

    # 方向性检测
    def way_5_or(self, num):
        if self.way_5_1(num) or self.way_5_2(num) or self.way_5_3(num) or self.way_5_4(num) :
            return True
        return False

    # 点检测
    def way_5_and(self, num):
        if self.way_5_1(num) and self.way_5_2(num) and self.way_5_3(num) and self.way_5_4(num) :
            return True
        return False

    # 斜向 \
    def way_5_1(self, num):
        n1 = self.block[0] + self.block[4] + self.block[8]
        if self.allin - n1 * 2 < num:
            return True
        return False
    # 斜向 /
    def way_5_2(self, num):
        n1 = self.block[2]+self.block[4]+self.block[6]
        if self.allin - n1 * 2 < num:
            return True
        return False
    # 横向 -
    def way_5_3(self, num):
        n1 = self.block[3]+self.block[4]+self.block[5]
        if self.allin - n1 * 2 < num:
            return True
        return False
    # 竖向 |
    def way_5_4(self, num):
        n1 = self.block[1] + self.block[4] + self.block[7]
        if self.allin - n1 * 2 < num:
            return True
        return False

lis = [[40000,120,-10,400,2]]
fit_li = ['3_0_1.jpg','3_0_2.jpg','3_0_3.jpg','3_0_4.jpg','3_0_5.jpg','3_0_6.jpg']
render = ['2_2_7_0.jpg', '2_2_11_10.jpg']
img = ImgFactory('3')
img.test_sorting(1800)
# img.sorting_img(lis)
# for i in range(len(fit_li)):
#     img.test_fit(fit_li[i], '3.jpg', i)
# img.save_temp(n=10)
# img.overlay('3.jpg', '3_1_11.jpg', 0)
# img.save_temp(n=100)